#pragma once

namespace RoomFW {

/// Simple windows critical section wrapper.  Instances of this
/// class may often be declared mutable to aid in const correctness.
/// See also http://msdn.microsoft.com/en-us/library/ms682530(VS.85).aspx
///
/// @author Andrew Sage
class SimpleCriticalSection
{
public:

	/// ctor
	SimpleCriticalSection(void);

	/// dtor
	~SimpleCriticalSection(void);

	/// Enter critical section, blocking and waiting if necessary.
	/// Prefer using a CriticalSectionGuard for exception safety.
	void enter(void);

	/// Enter critical section immediately.  
	/// Return 0 if failed (another thread already owns the lock).
	/// See also http://msdn.microsoft.com/en-us/library/ms686857(VS.85).aspx
	/// Prefer using a CriticalSectionGuard for exception safety.
	bool tryEnter(void);

	/// Leave critical section.  
	/// Prefer using a CriticalSectionGuardfor exception safety.
	void leave(void);

private:

	/// Windows critical section object.
	CRITICAL_SECTION cs_;

	/// Not copy-able!!!
	SimpleCriticalSection(const SimpleCriticalSection&);
	SimpleCriticalSection& operator=(const SimpleCriticalSection&);
};

//
// Class:	CriticalSectionGuard
//
// Description:	Constructor/Destructor critical section guard.  Use instead of
//				SimpleCriticalSection::enter/leave for exception safety.
//
// Author:	Andrew Sage
//
class CriticalSectionGuard
{
public:

	//
	// Method:	CriticalSectionGuard
	//
	// Description:	Constructor.  Enters critical section.
	//
	// Parameters:
	//
	//	cs - Critical section to guard.
	//
	CriticalSectionGuard(SimpleCriticalSection& cs);

	//
	// Method:	~SimpleCriticalSection
	//
	// Description:	Destructor.  Leaves critical section.
	//
	~CriticalSectionGuard(void);

private:

	//
	// Critical section to guard.
	//
	SimpleCriticalSection& cs_;
};

}

